# -*- coding: utf-8 -*-
# Created by Frank<fchen@robin8.com> on 2016-05-08 19:21
import operator
import math
from querier.esquerier import ElasticSearchQuerier
import jieba.posseg as pseg


RATE = 0.005
MAX_LEN = 128


class WechatGetKeywordsQuerier(ElasticSearchQuerier):
    def __init__(self, es, index, doc_type):
        super(WechatGetKeywordsQuerier, self).__init__(None, None, None)
        self.es = es
        self.index = index
        self.doc_type = doc_type

    def _build_query(self, args):
        ids = args.get('ids', None)
        if ids is None:
            raise ValueError('"ids" is needed.')

        query = {"query": {
            "constant_score": {
                "filter": {
                    "bool": {
                        "should": [
                            {"terms": {"article_id": ids}},
                        ]
                    }
                }
            }
        }, 'size': 50, 'sort': [{'publish_timestamp': 'desc'}]}
        return query, {}, {'ids': ids}

    def _build_result(self, es_result, param):
        keywords = []
        categories = {}
        ids = param['ids']
        out = {}
        for hit in es_result['hits']['hits']:
            o = extract_result(hit)
            out[o['article_id']] = {'keywords': o['keywords'], 'category': o['category']}

        for id_ in ids:
            o = out.get(id_, None)
            if o:
                keywords.append(o.get('keywords', []))
                cat = o['category']
                categories[cat] = categories.get(cat, 0) + 1
        keywords_extracted = get_keywords(keywords)
        # cats = class_0
        # diff = list(set(cats) - set(list(categories.keys())))
        # cat_list = sorted(categories, key=operator.itemgetter(1), reverse=True) + diff
        # cat_list = functools.reduce(lambda x, y: x+y,
        # [[cat] * (2 if v > 1 else v) for cat, v in categories.items()], [])
        return {
            'keywords': keywords_extracted,
            # 'categories': cat_list + diff[0:10]
        }


def extract_result(hit):
    source_ = hit['_source']
    return {
        'keywords': source_['keywords'],
        'category': source_['category'],
        'article_id': source_['article_id']
        }


# def get_keywords(keywords, rate=0.05):
def get_keywords(keywords):
    kv = {}
    length = len(keywords)
    # -math.log2((i+0.01)/(length+1))
    # math.exp(-i/length)

    weights = [math.exp(-i/length) for i in range(0, length)]

    for i in range(0, length):
        kw = keywords[i]
        for k in kw:
            if k not in ['公众', '微信', '微信号', '二维码', '蓝字', '关注', '点击', '如果', '联系', '时候', '然后', '因为', '问题', '公司']:
                a = pseg.lcut(k)
                # kv[k] = kv.get(k, 0) + 1
                if a:
                    if a[0].flag not in ['n', 'ns', 'nr']:
                        continue
                    else:
                        kv[k] = kv.get(k, 0) + 1 * weights[i]

    # values = list(kv.values())
    # s = 0
    min_weight = 1
    # if values:
    #     s = sum(values)
    #     min_weight = min(values) + 0.0001

    res = []
    for k, v in sorted(kv.items(), key=operator.itemgetter(1), reverse=True):
        # if v / (s + 0.0001) >= rate:
        res += [k] * (int(v / min_weight) if int(v / min_weight) < 2 else 2)
    return res
